﻿#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSettings>
#include <QStandardItemModel>
#include <QTimer>
#include <QPixmap>

#include "databaseinterface.h"
#include "datasimuthread.h"
#include "datasimustorage.h"
#include "videowindow.h"
#include "config/jsonconfig.h"
#include "config/xmlconfig.h"
#include "form/formrealtimedata.h"
#include "form/formrealtimeplot.h"
#include "form/formchannelcoefficient.h"
#include "form/formtestinfo.h"
#include "form/formhelp.h"
#include "communication/serialport.h"
#include "communication/udpserver.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QSettings* settings, DatabaseInterface* databaseInterface, QWidget *parent = nullptr);
    ~MainWindow() override;

protected:
    void keyPressEvent(QKeyEvent *event) override;
    void closeEvent(QCloseEvent *event) override;

private:
    void initConfig();
    void initUI();
    void initMenu();
    void initFlow();
    void initForm();
    void initStatus();
    void initVideo();
    void initGPIO();
    void init();
    void createAction();
    void loadStyle(const QString& stylePath);
    bool loadFlow(int level);
    void subflowToMap(const Subflow& subflow, QMap<QString, QVariant>& subflowMap);
    void traverseSubflowParent(QStandardItem* item, QStringList& nameList);
    void traverseSubflowChildren(QStandardItem* item, QList<Subflow>& subflowList);
    void traverseSubflowChildren(QStandardItem* item, bool check);
    void adjustPosition2Center(bool waitCommunication, bool runZero);
    int readGPIO7xLevel(int gpnum);

private:
    Ui::MainWindow *ui;

    // 串口打开/关闭指示灯, 复位/解除复位指示灯
    QPixmap m_grayPixmap;
    QPixmap m_greenPixmap;

    // 定时器
    QTimer* m_timer;

    // 流程模型
    QStandardItemModel* m_flowModel;
    // 流程右键菜单
    QMenu* m_flowContextMenu;

    // 页面: 实时数据, 实时曲线, 通道系数, 测试信息, 帮助
    FormRealtimeData* m_frmRealtimeData;
    FormRealtimePlot* m_frmRealtimePlot;
    FormChannelCoefficient* m_frmChannelCoefficient;
    FormTestInfo* m_frmTestInfo;
    FormHelp* m_frmHelp;

    // 状态栏
    QLabel* m_lblTesting;
    // 显示状态栏测试信息
    bool m_testingVisible;

    // 视频播放页面
    VideoWindow* m_videoWindow;
    bool m_videoVisible;

private:
    // INI配置文件
    QSettings* m_settings;
    // 数据访问接口
    DatabaseInterface* m_databaseInterface;
    // JSON配置文件
    JsonConfig* m_jsonConfig;
    // XML配置文件
    XmlConfig* m_xmlConfig;

    // 测试级别
    int m_level;

    // 是否正在进行初始位置调整
    bool m_adjusting;

    // Modbus485 RTU串口
    SerialPort* m_serialPort;
    // 串口打开标识
    bool m_opened;

    // 复位按键, 复位封锁按键
    int m_gpioReset;
    int m_gpioResetLatch;

    // 仿真时间间隔: ms
    int m_simuInterval;
    // 已采集点数
    int m_simuPoints;
    // 理论运行时间
    int m_theoryRunTime;

    // UDP通信
    UdpServer* m_udpServer;

    // 数据仿真线程
    DataSimuThread* m_dataSimuThread;
    // 数据存盘线程
    DataSimuStorage* m_dataSimuStorage;

signals:
    // 打开/关闭存储
    void sigOpenStorage();
    void sigCloseStorage();
    // UDP监听端口, 发送数据
    void sigUdpListen();
    void sigHeartBeat();
    // 训练结束
    void sigTrainEnd();
    // 操作上报: 1553
    void sigStepNotify(const QString stepCode);
    // 故障上报
    void sigFaultNotify(const QString faultCode, const int result);
    // 成绩打分
    void sigCourseScore();


private slots:
    void onTimeout();
    void onOpenSerialPort();
    void onSystemSet();
    void on1553();
    void onRun();
    void onTerminate();
    void onDataProcess();
    void onOneKey();
    void onFlowContextMenuPopup(const QPoint& pos);
    void onFlowItemSelectionChanged(const QModelIndex &current, const QModelIndex &previous);
    void onFlowItemCheckChanged(QStandardItem* item);
    void onLastPlot();
    void onQueryHistory();

public slots:
    void onErrorOccurred(QString error);
    void onPrepare();
    void onPrepareShow();
    void onUpdatePlot(const QStringList idList);
    void onTesingVisible(bool visible);
    void onTesting();
    void onUpdateChannelCoefficient(const QList<double>& coefficientList);
    void onFaultOccurred(const QString faultCode);
    void onStepNotify(const QString stepCode);
    void onStepWait(const QString stepName);
    void onSendCmd(const QString cmdName);
    void onSubflowFinished(const QString subflowName);
    void onCompleteFinished();
    void onCourseTrain(const QString courseNumber);

};
#endif // MAINWINDOW_H
